// AKShare 期权数据定时同步服务
// 
// 功能：
// 1. 每天下午3点半执行记录当天的期权数据
// 2. 每天早上8点检查如果没有上个交易日的数据，马上拉取并写入数据库

mod config;
mod scheduler;
mod sync;
mod trading_day;

use anyhow::{Context, Result};
use clap::Parser;
use tracing::{error, info};
use tracing_subscriber::{fmt, prelude::*, EnvFilter};

use config::SyncConfig;
use scheduler::Scheduler;

/// AKShare 期权数据定时同步服务
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// 配置文件路径
    #[arg(short, long, default_value = "config/sync_config.toml")]
    config: String,
    
    /// 立即执行一次同步（不启动定时任务）
    #[arg(short, long)]
    run_once: bool,
    
    /// 日志级别 (trace, debug, info, warn, error)
    #[arg(short, long, default_value = "info")]
    log_level: String,
}

#[tokio::main]
async fn main() -> Result<()> {
    // 解析命令行参数
    let args = Args::parse();
    
    // 初始化日志
    init_logging(&args.log_level)?;
    
    info!("AKShare 期权数据定时同步服务启动");
    info!("配置文件: {}", args.config);
    
    // 加载配置
    let config = SyncConfig::from_file(&args.config)
        .context("加载配置文件失败")?;
    
    info!("配置加载成功");
    info!("数据库路径: {}", config.database.path);
    info!("启用的数据源数量: {}", config.enabled_sources().len());
    
    if args.run_once {
        // 立即执行一次同步
        info!("执行一次性数据同步");
        run_once(config).await?;
    } else {
        // 启动定时任务
        info!("启动定时任务调度器");
        run_scheduler(config).await?;
    }
    
    info!("程序退出");
    Ok(())
}

/// 初始化日志系统
fn init_logging(level: &str) -> Result<()> {
    let env_filter = EnvFilter::try_from_default_env()
        .unwrap_or_else(|_| EnvFilter::new(level));
    
    tracing_subscriber::registry()
        .with(fmt::layer().with_target(true).with_thread_ids(true))
        .with(env_filter)
        .init();
    
    Ok(())
}

/// 执行一次性同步
async fn run_once(config: SyncConfig) -> Result<()> {
    let syncer = sync::DataSyncer::new(config)
        .await
        .context("创建数据同步器失败")?;
    
    syncer.sync_all().await.context("数据同步失败")?;
    
    info!("数据同步完成");
    Ok(())
}

/// 运行定时任务调度器
async fn run_scheduler(config: SyncConfig) -> Result<()> {
    let scheduler = Scheduler::new(config)
        .await
        .context("创建调度器失败")?;
    
    // 运行调度器（会阻塞直到收到停止信号）
    if let Err(e) = scheduler.run().await {
        error!("调度器运行失败: {}", e);
        return Err(e);
    }
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_args_parsing() {
        let args = Args::parse_from(&["test", "--config", "test.toml"]);
        assert_eq!(args.config, "test.toml");
        assert!(!args.run_once);
    }
    
    #[test]
    fn test_args_with_run_once() {
        let args = Args::parse_from(&["test", "--config", "test.toml", "--run-once"]);
        assert_eq!(args.config, "test.toml");
        assert!(args.run_once);
    }
    
    #[test]
    fn test_default_config_path() {
        let args = Args::parse_from(&["test"]);
        assert_eq!(args.config, "config/sync_config.toml");
        assert!(!args.run_once);
    }
    
    #[test]
    fn test_args_help() {
        // 测试帮助信息是否可以生成
        let result = Args::try_parse_from(&["test", "--help"]);
        assert!(result.is_err()); // --help 会导致退出，所以是 Err
    }
}
